1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.orekit.bodies;
18
19 import org.hipparchus.geometry.euclidean.threed.Vector3D;
20 import org.hipparchus.util.FastMath;
21 import org.orekit.time.AbsoluteDate;
22 import org.orekit.time.TimeScalesFactory;
23 import org.orekit.utils.Constants;
24
25
26
27
28
29
30
31
32
33
34
35
36 class IAUPoleFactory {
37
38
39
40
41
42
43 private IAUPoleFactory() {
44 }
45
46
47
48
49
50
51 public static IAUPole getIAUPole(final JPLEphemeridesLoader.EphemerisType body) {
52 switch (body) {
53 case SUN:
54 return new IAUPole() {
55
56
57 private static final long serialVersionUID = 5715331729495237139L;
58
59
60 public Vector3D getPole(final AbsoluteDate date) {
61 return new Vector3D(FastMath.toRadians(286.13),
62 FastMath.toRadians(63.87));
63 }
64
65
66 public double getPrimeMeridianAngle(final AbsoluteDate date) {
67 return FastMath.toRadians(84.176 + 14.1844000 * d(date));
68 }
69
70 };
71 case MERCURY:
72 return new IAUPole() {
73
74
75 private static final long serialVersionUID = -5769710119654037007L;
76
77
78 public Vector3D getPole(final AbsoluteDate date) {
79 final double t = t(date);
80 return new Vector3D(FastMath.toRadians(281.0097 - 0.0328 * t),
81 FastMath.toRadians( 61.4143 - 0.0049 * t));
82 }
83
84
85 public double getPrimeMeridianAngle(final AbsoluteDate date) {
86 final double[] m = computeMi(date);
87 return FastMath.toRadians(329.5469 + 6.1385025 * d(date) +
88 0.00993822 * FastMath.sin(m[0]) -
89 0.00104581 * FastMath.sin(m[1]) -
90 0.00010280 * FastMath.sin(m[2]) -
91 0.00002364 * FastMath.sin(m[3]) -
92 0.00000532 * FastMath.sin(m[4]));
93 }
94
95
96
97
98
99 private double[] computeMi(final AbsoluteDate date) {
100 final double d = d(date);
101 return new double[] {
102 FastMath.toRadians(174.791086 + 4.092335 * d),
103 FastMath.toRadians(349.582171 + 8.184670 * d),
104 FastMath.toRadians(164.373257 + 12.277005 * d),
105 FastMath.toRadians(339.164343 + 16.369340 * d),
106 FastMath.toRadians(153.955429 + 20.461675 * d),
107 };
108 }
109 };
110 case VENUS:
111 return new IAUPole() {
112
113
114 private static final long serialVersionUID = 7030506277976648896L;
115
116
117 public Vector3D getPole(final AbsoluteDate date) {
118 return new Vector3D(FastMath.toRadians(272.76),
119 FastMath.toRadians(67.16));
120 }
121
122
123 public double getPrimeMeridianAngle(final AbsoluteDate date) {
124 return FastMath.toRadians(160.20 - 1.4813688 * d(date));
125 }
126
127 };
128 case EARTH:
129 return new IAUPole() {
130
131
132 private static final long serialVersionUID = 6912325697192667056L;
133
134
135 public Vector3D getPole(final AbsoluteDate date) {
136 final double t = t(date);
137 return new Vector3D(FastMath.toRadians( 0.00 - 0.641 * t),
138 FastMath.toRadians(90.00 - 0.557 * t));
139 }
140
141
142 public double getPrimeMeridianAngle(final AbsoluteDate date) {
143 return FastMath.toRadians(190.147 + 360.9856235 * d(date));
144 }
145
146 };
147 case MOON:
148 return new IAUPole() {
149
150
151
152 private static final long serialVersionUID = -1310155975084976571L;
153
154
155 public Vector3D getPole(final AbsoluteDate date) {
156 final double[] e = computeEi(date);
157 final double t = t(date);
158 return new Vector3D(FastMath.toRadians(269.9949 + 0.0031 * t - 3.8787 * FastMath.sin(e[0]) -
159 0.1204 * FastMath.sin(e[1]) + 0.0700 * FastMath.sin(e[2]) -
160 0.0172 * FastMath.sin(e[3]) + 0.0072 * FastMath.sin(e[5]) -
161 0.0052 * FastMath.sin(e[9]) + 0.0043 * FastMath.sin(e[12])),
162 FastMath.toRadians( 66.5392 + 0.0130 * t + 1.5419 * FastMath.cos(e[0]) +
163 0.0239 * FastMath.cos(e[1]) - 0.0278 * FastMath.cos(e[2]) +
164 0.0068 * FastMath.cos(e[3]) - 0.0029 * FastMath.cos(e[5]) +
165 0.0009 * FastMath.cos(e[6]) + 0.0008 * FastMath.cos(e[9]) -
166 0.0009 * FastMath.cos(e[12])));
167 }
168
169
170 public double getPrimeMeridianAngle(final AbsoluteDate date) {
171 final double[] e = computeEi(date);
172 final double d = d(date);
173 return FastMath.toRadians(38.3213 + (13.17635815 - 1.4e-12 * d) * d + 3.5610 * FastMath.sin(e[0]) +
174 0.1208 * FastMath.sin(e[1]) - 0.0642 * FastMath.sin(e[2]) +
175 0.0158 * FastMath.sin(e[3]) + 0.0252 * FastMath.sin(e[4]) -
176 0.0066 * FastMath.sin(e[5]) - 0.0047 * FastMath.sin(e[6]) -
177 0.0046 * FastMath.sin(e[7]) + 0.0028 * FastMath.sin(e[8]) +
178 0.0052 * FastMath.sin(e[9]) + 0.0040 * FastMath.sin(e[10]) +
179 0.0019 * FastMath.sin(e[11]) - 0.0044 * FastMath.sin(e[12]));
180 }
181
182
183
184
185
186 private double[] computeEi(final AbsoluteDate date) {
187 final double d = d(date);
188 return new double[] {
189 FastMath.toRadians(125.045 - 0.0529921 * d),
190 FastMath.toRadians(250.089 - 0.1059842 * d),
191 FastMath.toRadians(260.008 + 13.0120009 * d),
192 FastMath.toRadians(176.625 + 13.3407154 * d),
193 FastMath.toRadians(357.529 + 0.9856003 * d),
194 FastMath.toRadians(311.589 + 26.4057084 * d),
195 FastMath.toRadians(134.963 + 13.0649930 * d),
196 FastMath.toRadians(276.617 + 0.3287146 * d),
197 FastMath.toRadians( 34.226 + 1.7484877 * d),
198 FastMath.toRadians( 15.134 - 0.1589763 * d),
199 FastMath.toRadians(119.743 + 0.0036096 * d),
200 FastMath.toRadians(239.961 + 0.1643573 * d),
201 FastMath.toRadians( 25.053 + 12.9590088 * d)
202 };
203 }
204
205 };
206 case MARS:
207 return new IAUPole() {
208
209
210 private static final long serialVersionUID = 1471983418540015411L;
211
212
213 public Vector3D getPole(final AbsoluteDate date) {
214 final double t = t(date);
215 return new Vector3D(FastMath.toRadians(317.68143 - 0.1061 * t),
216 FastMath.toRadians( 52.88650 - 0.0609 * t));
217 }
218
219
220 public double getPrimeMeridianAngle(final AbsoluteDate date) {
221 return FastMath.toRadians(176.630 + 350.89198226 * d(date));
222 }
223
224 };
225 case JUPITER:
226 return new IAUPole() {
227
228
229 private static final long serialVersionUID = 6959753758673537524L;
230
231
232 public Vector3D getPole(final AbsoluteDate date) {
233
234 final double t = t(date);
235 final double ja = FastMath.toRadians( 99.360714 + 4850.4046 * t);
236 final double jb = FastMath.toRadians(175.895369 + 1191.9605 * t);
237 final double jc = FastMath.toRadians(300.323162 + 262.5475 * t);
238 final double jd = FastMath.toRadians(114.012305 + 6070.2476 * t);
239 final double je = FastMath.toRadians( 49.511251 + 64.3000 * t);
240
241 return new Vector3D(FastMath.toRadians(268.056595 - 0.006499 * t +
242 0.000117 * FastMath.sin(ja) +
243 0.000938 * FastMath.sin(jb) +
244 0.001432 * FastMath.sin(jc) +
245 0.000030 * FastMath.sin(jd) +
246 0.002150 * FastMath.sin(je)),
247 FastMath.toRadians( 64.495303 + 0.002413 * t +
248 0.000050 * FastMath.cos(ja) +
249 0.000404 * FastMath.cos(jb) +
250 0.000617 * FastMath.cos(jc) -
251 0.000013 * FastMath.cos(jd) +
252 0.000926 * FastMath.cos(je)));
253 }
254
255
256 public double getPrimeMeridianAngle(final AbsoluteDate date) {
257 return FastMath.toRadians(284.95 + 870.5360000 * d(date));
258 }
259
260 };
261 case SATURN:
262 return new IAUPole() {
263
264
265 private static final long serialVersionUID = -1082211873912149774L;
266
267
268 public Vector3D getPole(final AbsoluteDate date) {
269 final double t = t(date);
270 return new Vector3D(FastMath.toRadians(40.589 - 0.036 * t),
271 FastMath.toRadians(83.537 - 0.004 * t));
272 }
273
274
275 public double getPrimeMeridianAngle(final AbsoluteDate date) {
276 return FastMath.toRadians(38.90 + 810.7939024 * d(date));
277 }
278
279 };
280 case URANUS:
281 return new IAUPole() {
282
283
284 private static final long serialVersionUID = 362792230470085154L;
285
286
287 public Vector3D getPole(final AbsoluteDate date) {
288 return new Vector3D(FastMath.toRadians(257.311),
289 FastMath.toRadians(-15.175));
290 }
291
292
293 public double getPrimeMeridianAngle(final AbsoluteDate date) {
294 return FastMath.toRadians(203.81 - 501.1600928 * d(date));
295 }
296
297 };
298 case NEPTUNE:
299 return new IAUPole() {
300
301
302 private static final long serialVersionUID = 560614555734665287L;
303
304
305 public Vector3D getPole(final AbsoluteDate date) {
306 final double n = FastMath.toRadians(357.85 + 52.316 * t(date));
307 return new Vector3D(FastMath.toRadians(299.36 + 0.70 * FastMath.sin(n)),
308 FastMath.toRadians( 43.46 - 0.51 * FastMath.cos(n)));
309 }
310
311
312 public double getPrimeMeridianAngle(final AbsoluteDate date) {
313 final double n = FastMath.toRadians(357.85 + 52.316 * t(date));
314 return FastMath.toRadians(253.18 + 536.3128492 * d(date) - 0.48 * FastMath.sin(n));
315 }
316
317 };
318 case PLUTO:
319 return new IAUPole() {
320
321
322 private static final long serialVersionUID = -1277113129327018062L;
323
324
325 public Vector3D getPole(final AbsoluteDate date) {
326 return new Vector3D(FastMath.toRadians(132.993),
327 FastMath.toRadians(-6.163));
328 }
329
330
331 public double getPrimeMeridianAngle(final AbsoluteDate date) {
332 return FastMath.toRadians(302.695 + 56.3625225 * d(date));
333 }
334
335 };
336 default:
337 return new GCRFAligned();
338 }
339 }
340
341
342
343
344
345 private static double t(final AbsoluteDate date) {
346 return date.offsetFrom(AbsoluteDate.J2000_EPOCH, TimeScalesFactory.getTDB()) / Constants.JULIAN_CENTURY;
347 }
348
349
350
351
352
353 private static double d(final AbsoluteDate date) {
354 return date.offsetFrom(AbsoluteDate.J2000_EPOCH, TimeScalesFactory.getTDB()) / Constants.JULIAN_DAY;
355 }
356
357
358
359
360
361
362
363
364 private static class GCRFAligned implements IAUPole {
365
366
367 private static final long serialVersionUID = 20130327L;
368
369
370 public Vector3D getPole(final AbsoluteDate date) {
371 return Vector3D.PLUS_K;
372 }
373
374
375 public double getPrimeMeridianAngle(final AbsoluteDate date) {
376 return 0;
377 }
378
379 }
380
381 }